using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;

namespace ShopForWeb.UI.Extensions
{
  /// <summary>
  /// Redis缓存对象扩展包
  /// </summary>
  public static class RedisCacheExtension
  {
    /// <summary>
    /// object 存入 缓存
    /// /// </summary>
    /// <param name="cache">缓存对象</param>
    /// <param name="key">存储用的key</param>
    /// <param name="value">待存储的对象</param>
    /// <param name="span">有效时间，单位分钟</param>
    /// <typeparam name="T">待存储对象的泛型</typeparam>
    public static void SetInstance<T>(this IDistributedCache cache, string key, T value, int span = 2)
    {
      cache.SetString(key, JsonConvert.SerializeObject(value), new DistributedCacheEntryOptions()
      {
        //AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(span),
        AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(span)
      });
    }

    /// <summary>
    /// object 取出 缓存
    /// </summary>
    /// <param name="cache">缓存对象</param>
    /// <param name="key">存储用的key</param>
    /// <typeparam name="T">待取出对象的泛型</typeparam>
    /// <returns>指定类型的object</returns>
    public static T? GetInstance<T>(this IDistributedCache cache, string key)
    {
      var value = cache.GetString(key);
      return value == null ? default : JsonConvert.DeserializeObject<T>(value);
    }

    /// <summary>
    /// object 存入 缓存 异步
    /// </summary>
    /// <param name="cache">缓存对象</param>
    /// <param name="key">存储用的key</param>
    /// <param name="value">待存储的对象</param>
    /// <param name="span">有效时间，单位分钟</param>
    /// <typeparam name="T">待存储对象的泛型</typeparam>
    /// <returns></returns>
    public static async Task SetInstanceAsync<T>(this IDistributedCache cache, string key, T value, int span = 2)
    {
      await cache.SetStringAsync(key, JsonConvert.SerializeObject(value), new DistributedCacheEntryOptions()
      {
        AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(span)
      });
    }

    /// <summary>
    /// object 取出 缓存 异步
    /// </summary>
    /// <param name="cache">缓存对象</param>
    /// <param name="key">存储用的key</param>
    /// <typeparam name="T">待取出对象的泛型</typeparam>
    /// <returns>指定类型的object</returns>
    public static async Task<T?> GetInstanceAsync<T>(this IDistributedCache cache, string key)
    {
      var value = await cache.GetStringAsync(key);
      return value == null ? default : JsonConvert.DeserializeObject<T>(value);
    }


  }
}
